package cuppics;

import org.junit.Test;

public class Prj19 {

	/**
	 * You are given the following information, but you may prefer to do some
	 * research for yourself.
	 * 
	 * 1 Jan 1900 was a Monday. Thirty days has September, April, June and
	 * November. All the rest have thirty-one, Saving February alone, Which has
	 * twenty-eight, rain or shine. And on leap years, twenty-nine. A leap year
	 * occurs on any year evenly divisible by 4, but not on a century unless it
	 * is divisible by 400. How many Sundays fell on the first of the month
	 * during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
	 */
	@Test
	public void test() {
		System.out.println(Calculator.calculateSundays(new TmYear(1901, 1, 1),
				new TmYear(2000, 12, 13)));

	}

	public static class Calculator {

		public static int calculateSundays(TmYear start, TmYear end) {
			int sundays = -1;
			int remain = 2; // 1 is sunday
			while (!start.equals(end)) {

				if (start.day == 1 && remain == 1) {
					sundays += 1;
				}

				start = start.add(TmUnit.DAY);
				remain += 1;

				if (remain > 7) {
					remain = 1;
				}
			}

			System.out.println("sundays=" + sundays);
			return sundays;
		}

		public static boolean isLeapyear(int year) {

			return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
		}

	}

	public static enum TmUnit {
		DAY
	}

	public static class TmYear {

		public static final int[] DAYS_LIST = { 0, 31, 28, 31, 30, 31, 30, 31,
				31, 30, 31, 30, 31 };

		public static final int[] DAYS_LEAP_LIST = { 0, 31, 29, 31, 30, 31, 30,
				31, 31, 30, 31, 30, 31 };

		public int year;
		public int month;
		public int day;

		public TmYear(int year, int month, int day) {
			this.year = year;
			this.month = month;
			this.day = day;
		}

		public TmYear() {
			this(1900, 1, 1);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {

			return this.year + "-" + this.month + "-" + this.day;
		}

		public TmYear add(TmUnit unit) {

			if (unit != TmUnit.DAY) {
				return null;
			}

			TmYear tm = new TmYear(this.year, this.month, this.day);

			int day = tm.day;
			int month = tm.month;
			int year = tm.year;

			if ((!Calculator.isLeapyear(year) && day == DAYS_LIST[month])
					|| (Calculator.isLeapyear(year) && day == DAYS_LEAP_LIST[month])) {

				tm.day = 1;
				if (month == 12) {
					tm.month = 1;
					tm.year += 1;
					return tm;

				} else {
					tm.month += 1;
					return tm;
				}

			} else {
				tm.day += 1;
				return tm;
			}

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + day;
			result = prime * result + month;
			result = prime * result + year;
			return result;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj == null) {
				return false;
			}
			if (!(obj instanceof TmYear)) {
				return false;
			}
			TmYear other = (TmYear) obj;
			if (day != other.day) {
				return false;
			}
			if (month != other.month) {
				return false;
			}
			if (year != other.year) {
				return false;
			}
			return true;
		}

	}

}
